//命令模块
#pragma once

#include<iostream>
#include<string>
#include<set>
#include"Common.hpp"
#include"InetAddr.hpp"
#include"Log.hpp"

using namespace LogModule;

class Command
{
public:
    Command()
    {
        //对于命令需要严格匹配
        _WhiteListCommands.insert("ls");
        _WhiteListCommands.insert("pwd");
        _WhiteListCommands.insert("ls -l");
        _WhiteListCommands.insert("touch haha.txt");
        _WhiteListCommands.insert("who");
        _WhiteListCommands.insert("whoami");
    }

//查找判断命令是否在白名单中
    bool IsSafeCommand(const std::string &cmd)
    {
        auto iter = _WhiteListCommands.find(cmd);
        return iter != _WhiteListCommands.end();
    }

//第一个参数:命令     第二个参数：是谁
    std::string Execute(const std::string &cmd,InetAddr &addr)
    {
        //1.白名单命令
        if(!IsSafeCommand(cmd))
        {
            return std::string("这不是合法白名单指令！！！");
        }

        std::string who = addr.StringAddr();     //把客户端也给拿出来

        //2.执行命令
        FILE *fp = popen(cmd.c_str(),"r");    //以读的方式打开
        if(nullptr == fp)
        {
            return std::string("你要执行的命令不存在: ")+cmd;   //底层会创建管道
        }
        std::string res;
        char line[1024];    //缓冲区
        while(fgets(line,sizeof(line),fp));    //fgets 从文件读取     参数：缓冲区   大小   文件流
        {
            res += line;
        }
        pclose(fp);

        std::string result = who + "excute done,result is: \n" + res;    //会发现IP地址和这个命令   下一命令执行的结果
        LOG(LogLevel::DEBUG) << result;     //打印一个日志
        return result;
    }

    ~Command()
    {}


private:
    //受限制的命令执行   白名单命令执行
     std::set<std::string> _WhiteListCommands;    //白名单命令集合（只允许执行这里面的命令来了）

};
